package org.bhf.providers.security.password;

import org.bhf.security.password.PasswordGenerator;

import java.util.Random;

public class PronouncablePasswordGenerator implements PasswordGenerator
{
    private static Random random = new Random();

    private static String[] vowels = {
        "a",
        "e",
        "i",
        "o",
        "u"
    };
    private static String[] consonants = {
        "b",
        "c",
        "d",
        "f",
        "g",
        "h",
        "j",
        "k",
        "l",
        "m",
        "n",
        "p",
        "r",
        "s",
        "t",
        "v",
        "z",
        "th",
        "ch",
        "sh"
    };

    private int minimumLength = 8;

    /**
     * Set the minimum password length to use when a minimum password length is not specified.
     * @param minimumLength The minimum password length to use when a minimum password length is not specified.
     */
    public void setMinimumLength( final int minimumLength )
    {
        this.minimumLength = minimumLength;
    }

    /**
     * @inheritDoc
     */
    public String   generate()
    {
        return generate( minimumLength );
    }

    /**
     * @inheritDoc
     */
    public String   generate( final int minimumLength )
    {
        final StringBuffer patternBuffer = new StringBuffer();
        for( int i = 0; i < minimumLength; i += 2 )
        {
            patternBuffer.append( 'b' );
            patternBuffer.append( 'a' );
        }
        patternBuffer.append( '1' );

        final String        pattern     = patternBuffer.toString();
        final StringBuffer  password    = new StringBuffer();

        for( final char s : pattern.toCharArray() )
        {
            switch( s )
            {
                case 'b':
                    password.append( consonants[ Math.abs( random.nextInt() ) % consonants.length ] );
                    break;
                case 'a':
                    password.append( vowels[ Math.abs( random.nextInt() ) % vowels.length ] );
                    break;
                case '1':
                    password.append( Math.abs( random.nextInt() ) % 10 );
                    break;
            }
        }

        return password.toString();
    }

    /**
     * @inheritDoc
     * @exclude
     */
    public void validateConfiguration()
        throws IllegalArgumentException
    {
        if( minimumLength < 1 )
            throw new IllegalArgumentException( "PronouncablePasswordGenerator configured with a minimumLength < 1" );
    }

    /**
     * @inheritDoc
     * @exclude
     */
    public Object decorate()
    {
        return this;
    }
}